/*
 * Package il.ac.biu.cs.grossmm.impl.keys
 * File KeyOperations.java
 * 
 * This is a part of presence service framework prototype. 
 * See javadoc for more information.
 *  
 * Copyright (C) 2006 Grossmann Mark
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package il.ac.biu.cs.grossmm.impl.keys;

import il.ac.biu.cs.grossmm.api.keys.*;

public class KeyOperations {

	/**
	 * Given a data key, out and in patterns, for each entry KE in the key if
	 * there is an entry PE' in the out pattern with the same attribute, removes
	 * this entry, then adds all entries from the in pattern, replacing any
	 * entries with the same attributes.
	 * <p>
	 * in and out patterns must be mask patterns, all their entries should be
	 * mandatory. out pattern not refer to value-classes (true recusrively)
	 * 
	 * @param pattern
	 * @param mask
	 * @return
	 */
	public static Key transform(Key key, KeyPattern out, KeyPattern in)
	{
		ArrayKey result = new ArrayKey(key.value());

		int size = key.size();

		// add all entries from target where entry attribute does
		// not match any entry in the in or out patterns
		for (int i = 0; i < size; i++) {
			KeyEntry e = key.entry(i);
			Attribute a = e.getAttribute();

			if (in.entry(a) == null && out.entry(a) == null)
				result.addKey(e);
		}

		size = in.size();

		for (int i = 0; i < size; i++) {
			PatternEntry e = in.entry(i);
			Key subKey = patternToKey(e.getPattern());
			result.addKey(e.getAttribute(), subKey);
		}

		return result;
	}

	public static Key patternToKey(KeyPattern pattern)
	{
		int size = pattern.size();

		if (size == 0)
			return new SimpleKey(pattern.value());

		ArrayKey key = new ArrayKey(pattern.value());

		for (int i = 0; i < size; i++) {
			PatternEntry pe = pattern.entry(i);
			Key subKey = patternToKey(pe.getPattern());
			key.addKey(pe.getAttribute(), subKey);
		}

		return key;
	}
}
